home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / standards / sgml / nist / parse1 / dtdent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-13  |  16.5 KB  |  450 lines

  1. /* National Institute of Standards and Technology (NIST)
  2. /* National Computer System Laboratory (NCSL)
  3. /* Office Systems Engineering (OSE) Group
  4. /* ********************************************************************
  5. /*                            D I S C L A I M E R
  6. /*                              (March 8, 1989)
  7. /*  
  8. /* There is no warranty for the NIST NCSL OSE SGML parser and/or the NIST
  9. /* NCSL OSE SGML parser validation suite.  If the SGML parser and/or
  10. /* validation suite is modified by someone else and passed on, NIST wants
  11. /* the parser's recipients to know that what they have is not what NIST
  12. /* distributed, so that any problems introduced by others will not
  13. /* reflect on our reputation.
  14. /* 
  15. /* Policies
  16. /* 
  17. /* 1. Anyone may copy and distribute verbatim copies of the SGML source
  18. /* code as received in any medium.
  19. /* 
  20. /* 2. Anyone may modify your copy or copies of SGML parser source code or
  21. /* any portion of it, and copy and distribute such modifications provided
  22. /* that all modifications are clearly associated with the entity that
  23. /* performs the modifications.
  24. /* 
  25. /* NO WARRANTY
  26. /* ===========
  27. /* 
  28. /* NIST PROVIDES ABSOLUTELY NO WARRANTY.  THE SGML PARSER AND VALIDATION
  29. /* SUITE ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
  30. /* EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31. /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  32. /* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
  33. /* WITH YOU.  SHOULD THE SGML PARSER OR VALIDATION SUITE PROVE DEFECTIVE,
  34. /* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  35. /* 
  36. /* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL NIST BE LIABLE FOR
  37. /* DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
  38. /* INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
  39. /* INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
  40. /* BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
  41. /* FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
  42. /* NIST) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
  43. /* SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
  44. */
  45.  
  46. /************************************************************************/
  47. /*   TITLE:          SGML PARSER                                        */
  48. /*   SYSTEM:         DTD PROCESSOR                                      */
  49. /*   SUBSYSTEM:                                                         */
  50. /*   SOURCE FILE:    DTDSUTIL.C                                         */
  51. /*   AUTHOR:         Michael Garris                                     */
  52. /*                                                                      */
  53. /*   DATE CREATED:                                                      */
  54. /*   LAST MODIFIED:                                                     */
  55. /*                                                                      */
  56. /*                  REVISIONS                                           */
  57. /*   WHEN      WHO            WHY                                       */
  58. /************************************************************************/
  59. #include <stdio.h>
  60. #include <setjmp.h>
  61. #include "qntyset.h"
  62. #include "dtd.h"
  63. #include "dtdfncs.h"
  64. #include "dtddefs.h"
  65. #include "dtdglbl.h"
  66. /************************************************************************/
  67. /* globals for linked list used for resolving entity references         */
  68. /************************************************************************/
  69. static SYMBOL   Nsymbol; /* structure containing: 
  70.                            name, syntactic literal, parameter literal */
  71.  
  72.  
  73. static NODE   *Phead = NULL;/* pointer to first NODE in parameter entity 
  74.                                linked list, initialized to NULL */
  75.  
  76. static NODE   *Ghead = NULL;/* pointer to first NODE in general entity
  77.                                linked list, initialized to NULL */
  78.  
  79. /************************************************************************/
  80. /* doentity() is the main module for processing any entity declaration. */
  81. /* It calls routines to input PS's, get the entity name, and get the    */
  82. /* entity text building 2 pairs of tables, 1 (parameter entity, general */
  83. /* entity) pair as linked lists, and the second (parameter entity,      */
  84. /* general entity) pair as output to file.                              */
  85. /************************************************************************/
  86. void doentity()
  87. {
  88.    char *nameptr, *litptr;
  89.    int synkey;
  90.    int pscount;
  91.    int enttype;
  92.    int c;
  93.  
  94.    pscount = INPPS();
  95.    nameptr = getentname(pscount, &enttype);
  96.    pscount = INPPS();
  97.    synkey = getenttext(pscount, &litptr, enttype);
  98.    pscount = INPPS();
  99.    ADDCHAR(SPACE);
  100.    if((c = jgetc()) == EOF)
  101.       terminate(1, "End of File found while expecting MDO");
  102.    if(c == MDC) {
  103.       buildtbl(enttype, nameptr, synkey, litptr);
  104.       ADDCHAR(MDC);
  105.    }
  106.    else{
  107.       ADDCHAR(c);
  108.       jungetc(c);
  109.       syntxerr("MDC not found in entity declaration");
  110.    }
  111. }
  112.  
  113. /************************************************************************/
  114. /* getentname() gets a valid entity name determining if the name is a   */
  115. /* valid general entity name or a valid parameter entity name.          */
  116. /************************************************************************/
  117. char *getentname(pscount, typeptr)
  118. int pscount;
  119. int *typeptr;
  120. {
  121.    static char namearray[NAMELEN + 1], *nptr;
  122.    int c, j;
  123.  
  124.    nptr = namearray;
  125.    if((c = jgetc()) == EOF)
  126.       terminate(1, "EOF found");
  127.    if(c != PERO){
  128.       /* then general entity declaration */
  129.       *typeptr = GEN_ENT_NAME;
  130.       if(pscount == 0)
  131.          syntxerr("Required PS not found");
  132.       jungetc(c);
  133.       j = INPRNINAME( &nptr, NAMELEN, noxlat);
  134.       if (namearray[0] == RNI)
  135.          if(strcmp(namearray, "#DEFAULT") != 0){
  136.             ADDCHAR(SPACE);
  137.             ADDSTRING(namearray);
  138.             syntxerr("Illegal use of RNI in entity name");
  139.          }
  140.    }
  141.    else{
  142.       /* else parameter entity declaration */
  143.       *typeptr = PARM_ENT_NAME;
  144.       ADDCHAR(SPACE);
  145.       ADDCHAR(PERO);
  146.       if(INPPS() >= 1)
  147.          j = INPNAME( &nptr, NAMELEN - 1, noxlat);
  148.       else
  149.          syntxerr("Required PS not found in parameter entity name");
  150.    }
  151.    ADDCHAR(SPACE);
  152.    ADDSTRING(namearray);
  153.    if(j >= GOOD)
  154.       return(namearray);
  155.    else
  156.       syntxerr("Entity name not found");
  157.    /* should not be reached, only for lint */
  158.    return(namearray);
  159. }
  160.  
  161. /************************************************************************/
  162. /* getenttext() gets the entity text for any entity declaration.  It    */
  163. /* inputs a syntactic literal which may be NULL, PS's, and a parameter  */
  164. /* literal.                                                             */
  165. /************************************************************************/
  166. int getenttext(pscount, litptr, enttype)
  167. int pscount;
  168. char **litptr;
  169. int enttype;
  170. {
  171.    char namearray[NAMELEN + 1], *nameptr = namearray;
  172.    static char litarray[LITLEN + 1];
  173.    char *lptr;
  174.    int j, jj, synlitsize;
  175.  
  176.    lptr = litarray;
  177.    memset(litarray, '\0', LITLEN);
  178.    if((j = INPNAME(&nameptr, NAMELEN, TOUPPER)) == EOF)
  179.       terminate(1, "EOF found in entity declaration");
  180.    switch (j){
  181.  
  182.    case KW_SYSTEM:
  183.    case KW_PUBLIC:
  184.       if(pscount < 1)
  185.          syntxerr("PS not found before syntactic literal in data text");
  186.       ADDCHAR(SPACE);
  187.       ADDSTRING(synliteral(j));
  188.       ADDCHAR(SPACE);
  189.       /* call procedure to input the parameter literal */
  190.       if (j == KW_SYSTEM)
  191.          dosystem(YES);
  192.       else dopublic(YES);
  193.       if (INPPS() == EOF)
  194.          terminate(1, "EOF found in entity declaration");
  195.       ADDCHAR(SPACE);
  196.       nameptr = namearray;
  197.       if((jj = INPNAME(&nameptr, NAMELEN, TOUPPER)) == EOF)
  198.          terminate(1, "EOF found in entity declaration");
  199.       if (jj < GOOD)
  200.          return(j);
  201.       ADDSTRING(namearray);
  202.       if (jj != KW_NDATA)
  203.          syntxerr("illegal syntactic keyword");
  204.       else if (enttype != GEN_ENT_NAME)
  205.          syntxerr("General entity name required when using entity type");
  206.       if (INPPS() == EOF)
  207.          terminate(1, "EOF found in entity declaration");
  208.       nameptr = litarray;
  209.       if((jj = INPNAME(&nameptr, NAMELEN, TOUPPER)) == EOF)
  210.          terminate(1, "EOF found in entity declaration");
  211.       if (jj < GOOD)
  212.          syntxerr("expected NOTATION NAME");
  213.       *litptr = litarray;
  214.       return(j);
  215.       /* cases for DATA TEXT */
  216.    case KW_CDATA:
  217.    case KW_SDATA:
  218.       /* CDATA and SDATA may only be used with in a general entity decl */
  219.       if(enttype == PARM_ENT_NAME){
  220.          ADDCHAR(SPACE);
  221.          ADDSTRING(synliteral(j));
  222.          syntxerr("Illegal use of data text while processing entity text");
  223.       }
  224.    case KW_PI:
  225.       if(pscount < 1)
  226.          syntxerr("PS not found before syntactic literal in data text");
  227.       ADDCHAR(SPACE);
  228.       ADDSTRING(synliteral(j));
  229.       if (INPPS() == EOF)
  230.          terminate(1, "EOF found in entity declaration");
  231.       ADDCHAR(SPACE);
  232.       /* call procedure to input the parameter literal */
  233.       inpparmlit(&lptr);
  234.       *litptr = litarray;
  235.       /* return the syntactic literal */
  236.       return(j);
  237.  
  238.       /* cases for BRAKETED TEXT */
  239.    case KW_STARTTAG:
  240.       synlitsize = STARTTAGSIZE;
  241.       goto SHARE;
  242.    case KW_ENDTAG:
  243.       synlitsize = ENDTAGSIZE;
  244.       goto SHARE;
  245.    case KW_MS:
  246.       synlitsize = MSSIZE;
  247.       goto SHARE;
  248.    case KW_MD:
  249.       synlitsize = MDSIZE;
  250. SHARE:
  251.       if(pscount < 1)
  252.          syntxerr("PS not found before syntactic literal in braketed text");
  253.       ADDCHAR(SPACE);
  254.       ADDSTRING(synliteral(j));
  255.       INPPS();
  256.       ADDCHAR(SPACE);
  257.       /* call procedure to input parameter literal */
  258.       inpparmlit(&lptr);
  259.       *litptr = litarray;
  260.       /* if the length of the parameter literal plus the length of */
  261.       /* the corresponding bracketed text delimeters exceeds LITLEN */
  262.       /* then ERROR */
  263.       if((synlitsize + strlen(litarray)) > LITLEN)
  264.          syntxerr("LITLEN exceeded in interpreted bracketed text.");
  265.       /* return the syntactic literal */
  266.       return(j);
  267.       /* If BAD name, ie. NULL syntactice literal, then check if */
  268.       /* there exists a parameter literal */
  269.    case BAD:
  270.       if((j = jgetc()) == EOF)
  271.          terminate(1, "End of File found while processing entity text");
  272.       /* if a parameter literal does not exist then ERROR */
  273.       if((j != LITA) && (j != LIT)){
  274.          ADDCHAR(j);
  275.          jungetc(j);
  276.          syntxerr("Entity text not found");
  277.       }
  278.       jungetc(j);
  279.       ADDCHAR(SPACE);
  280.       /* else call procedure to input parameter literal */
  281.       inpparmlit(&lptr);
  282.       *litptr = litarray;
  283.       return(NULL);
  284.    default:
  285.       /* syntactic literal found out of context */
  286.       ADDCHAR(SPACE);
  287.       ADDSTRING(synliteral(j));
  288.       syntxerr("Entity text not found");
  289.    }
  290.    /*should never be reached, for lint only*/
  291.    return(BAD);
  292. }
  293.  
  294. /************************************************************************/
  295. /* search() determines the type of a name passed (parameter, general)   */
  296. /* and searches through the appropriate linked list for a match on the  */
  297. /* name. If the name is found, it returns the syntactic literal and     */
  298. /* parameter literal text. Otherwise, if the name is not found or the   */
  299. /* list is empty, the procedure returns an error flag value.            */
  300. /************************************************************************/
  301. int search(enttype, nptr, litptr)
  302. int enttype;
  303. char *nptr, **litptr;
  304. {
  305.    NODE *Ncurrptr;
  306.    NODE *head;
  307.    char *lptr = *litptr;
  308.  
  309.    mprintf("Entered [search].\n");
  310.    /* if entity name being searched for is a parameter entity name ... */
  311.    if(enttype == PARM_ENT_NAME)
  312.       /* search the parameter entity linked list */
  313.       head = Phead;
  314.    else
  315.       /* else the name is a general entity name, so search the general */
  316.       /* entity linked list. */
  317.       head = Ghead;
  318.    /* if linked list is not empty ... */
  319.    if(head != NULL){
  320.       Ncurrptr = head;
  321.       /* while no match on name and not at end of linked list ... */
  322.       while((strcmp(nptr, Ncurrptr -> Nsymbol.SSname) != 0)
  323.           && (Ncurrptr -> Nnextptr != NULL))
  324.          Ncurrptr = Ncurrptr -> Nnextptr;
  325.       /* if match on name ... */
  326.       if(strcmp(nptr, Ncurrptr -> Nsymbol.SSname) == 0){
  327.          lptr = Ncurrptr -> Nsymbol.Sdef;
  328.          *litptr = lptr;
  329.          return(Ncurrptr -> Nsymbol.Ssynkey);
  330.       }
  331.    }
  332.    /* else either linked list empty or name not found in list */
  333.    *litptr = lptr;
  334.    /* so return error flag */
  335.    return(ILLCHAR);
  336. }
  337.  
  338. /************************************************************************/
  339. /* buildtbl() determines what type of entity name is passed and adds a  */
  340. /* new node to the appropriate linked list and calls a procedure which  */
  341. /* adds a record of info to the appropriate file table.                 */
  342. /************************************************************************/
  343. void buildtbl(enttype, nameptr, synkey, litptr)
  344. int enttype, synkey;
  345. char *nameptr, *litptr;
  346. {
  347.    NODE *Nnode, *Ncurrptr;
  348.    char *malloc();
  349.    NODE **headptr;
  350.  
  351.    /* if parameter entity name, then use parameter entity linked list */
  352.    if(enttype == PARM_ENT_NAME)
  353.       headptr = &Phead;
  354.    else
  355.       /* else use the general entity linked list */
  356.       headptr = &Ghead;
  357.    mprintf("Entered [buildtbl].\n");
  358.    /* allocate memory for a new NODE */
  359.    Nnode = (NODE *)(malloc(sizeof(NODE)));
  360.    if(Nnode == 0)
  361.       terminate(1, "Unable to allocate memory using malloc");
  362.    /* set the node pointer in Nnode to NULL because it will added to the */
  363.    /* end of the existing linked list */
  364.    Nnode -> Nnextptr = NULL;
  365.    mprintf("Calling [buildsymbol] from [buildtbl].\n");
  366.    /* call procedure which adds to the appropriate file table and */
  367.    /* sets up Nnode with valid data */
  368.    buildandwritesymbol(enttype, &(Nnode -> Nsymbol), nameptr, synkey, litptr);
  369.    /* if the list is empty, then simply make */
  370.    /* Nnode the first node in the list */
  371.    if(*headptr == NULL)
  372.       *headptr = Nnode;
  373.    else{
  374.       /* else search the appropriate linked list to the end of the list */
  375.       Ncurrptr = *headptr;
  376.       while(Ncurrptr -> Nnextptr != NULL)
  377.          Ncurrptr = Ncurrptr -> Nnextptr;
  378.       /* and add Nnode to the end of the list */
  379.       Ncurrptr -> Nnextptr = Nnode;
  380.    }
  381.    mprintf("Exiting [buildtbl].\n");
  382. }
  383.  
  384. /************************************************************************/
  385. /* buildandwritesymbol() is a procedure which updates the appropriate   */
  386. /* file table according to whether the entity name is a parameter or    */
  387. /* general entity name. It also fills the node which is to be added to  */
  388. /* the appropriate linked list with proper data.                        */
  389. /************************************************************************/
  390. void buildandwritesymbol(enttype, symbol, nameptr, synkey, litptr)
  391. int enttype;
  392. SYMBOL *symbol;
  393. char *nameptr;
  394. int synkey;
  395. char *litptr;
  396. {
  397.    int litlen,i;
  398.    char namebuff[NAMELEN];
  399.    char *nptr,*namebuffptr;
  400.  
  401.    mprintf("Entered [buildsymbol].\n");
  402.    nptr = nameptr;
  403.    namebuffptr = namebuff;
  404.    /* put the name passed into a buffer which is right padded with spaces */
  405.    for(i = 0; i < NAMELEN; ++i)
  406.       *namebuffptr++ = ' ';
  407.    namebuffptr = namebuff;
  408.    while(*nptr != '\0')
  409.       *namebuffptr++ = *nptr++;
  410.  
  411.    litlen = strlen(litptr) + 1;
  412.    /* call procedure which actually writes the data to the appropriate file */
  413.    writerecord(enttype, namebuff, synkey, litptr, litlen);
  414.    /* copy the entity name into a node to be added to the linked list */
  415.    strcpy (symbol->SSname, nameptr);
  416.    /* copy the syntactic literal into the node to be added */
  417.    symbol -> Ssynkey = synkey;
  418.    /* copy the parameter literal ext into the node */
  419.    strcpy (symbol -> Sdef, litptr);
  420.    mprintf("Exiting [buildsymbol].\n");
  421. }
  422.  
  423. /********************************************************************/
  424. /* writerecord() writes a record of data into the appropriate file  */
  425. /* table using a procedure called safewrite.                        */
  426. /********************************************************************/
  427. void writerecord(enttype, nameptr, synkey, litptr, litlen)
  428. int enttype;
  429. char *nameptr, *litptr;
  430. int synkey, litlen;
  431. {
  432.    int file;
  433.  
  434.    /* if entity a parameter entity then use parameter entity file table */
  435.    if(enttype == PARM_ENT_NAME)
  436.       file = preffile;
  437.    else
  438.       /* else use the general entity file table */
  439.       file = greffile;
  440.    /* first field = length of parameter literal text */
  441.    safewrite(file,(char *)&litlen,sizeof(litlen));
  442.    /* second field = entity name */
  443.    safewrite(file, nameptr, (unsigned)(NAMELEN));
  444.    /* third field = syntactic literal */
  445.    safewrite(file,(char *)&synkey, sizeof(synkey));
  446.    /* fourth field = parameter literal text */
  447.    safewrite(file, litptr, (unsigned)litlen);
  448. }
  449. /* ================================================================ */
  450.